package com.nineclock.auth.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.nineclock.auth.entity.IntegrationAuthenticationEntity;
import com.nineclock.auth.entity.IntegrationAuthenticationHolder;
import com.nineclock.auth.entity.UserHolder;
import com.nineclock.auth.processor.AuthenticationProcessor;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.JsonUtils;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysRoleDTO;
import com.nineclock.system.dto.SysUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Component
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

//    自动注入所有的 认证处理器到集合中
    @Autowired
    List<AuthenticationProcessor> processorList;

    @Autowired
    SysUserFeign sysUserFeign;

    //明文密码为 123456
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        从线程中获取处理器对象
        IntegrationAuthenticationEntity entity = IntegrationAuthenticationHolder.get();
        AuthenticationProcessor processor = this.chooseAuthenticationProcessor(entity);

        SysUserDTO sysUserDTO = processor.authenticate(entity);
        if (sysUserDTO==null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }


        UserInfo userInfo = BeanHelper.copyProperties(sysUserDTO, UserInfo.class);


        //获取client_id
        String clientId = entity.getAuthParameter("client_id");
        String companyId = entity.getAuthParameter("company_id");

        userInfo.setClientId(clientId);

        if (clientId != null && clientId.equals("pc_client")){
//            是pc端，管理员才能登录
            if (StrUtil.isNotEmpty(companyId)){
                //展示了企业列表， 选择了某个企业
                //根据企业id和用户id获取 企业员工信息, 且包含角色信息
                List<SysCompanyUserDTO> companyUserDTOList = sysUserFeign.queryCompanyUser(sysUserDTO.getId(), Long.valueOf(companyId)).getData();

                if(CollectionUtil.isEmpty(companyUserDTOList)){
                    throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
                }
                //判断企业员工是否是管理员, 如果是管理员，继续登录， 如果不是管理员，提示 ‘您不是管理员’
                if (!this.checkAdmin(companyUserDTOList)){
                    throw new NcException(ResponseEnum.USER_NOT_COMPANY_ADMIN);
                }

                // 把企业信息 封装到userInfo中， 最终此对象存入到token中
                this.wrapper(userInfo, companyUserDTOList);

            }else {
                //点击登录，没有选择企业， 根据用户id查询企业列表
                List<SysCompanyUserDTO> companyUserDTOList = sysUserFeign.queryCompanyUser( sysUserDTO.getId(),null).getData();
                if(CollectionUtil.isEmpty(companyUserDTOList)){
                    throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
                }
                if(!this.checkAdmin(companyUserDTOList)){
                    throw new NcException(ResponseEnum.USER_NOT_COMPANY_ADMIN);
                }

                // 把企业信息 封装到userInfo中， 最终此对象存入到token中
                this.wrapper(userInfo, companyUserDTOList);
            }
        }else{

            //是 app端， 只要是用户即可登录
            //如果没有传企业id， 默认使用最后一次登录使用的企业id
            if(StrUtil.isEmpty(companyId)){
                companyId = String.valueOf(sysUserDTO.getLastLoginCompanyId());
            }

            List<SysCompanyUserDTO> companyUserDTOList = sysUserFeign.queryCompanyUser(sysUserDTO.getId(),Long.valueOf(companyId)).getData();
            //如果查询到了员工信息， 封装到userInfo中
            if(CollectionUtil.isNotEmpty(companyUserDTOList) && companyUserDTOList.size() == 1){
                wrapper(userInfo, companyUserDTOList);
            }

        }

        UserHolder.set(userInfo);
        List<GrantedAuthority> authorityList=new ArrayList<>();
        authorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        //        封装userdto对象
        User user=new User(JsonUtils.toString(userInfo),sysUserDTO.getPassword(),authorityList);

        return user;
    }

    /**
     * 判断是否是管理员
     * @param companyUserDTOList
     * @return
     */
    private boolean checkAdmin(List<SysCompanyUserDTO> companyUserDTOList) {
        if(companyUserDTOList != null){
            for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
                //获取权限信息
                List<SysRoleDTO> roleDtoList = companyUserDTO.getRoles();
                for (SysRoleDTO sysRoleDTO : roleDtoList) {
                    //获取角色名称
                    String roleName = sysRoleDTO.getRoleName();
                    if(roleName != null && roleName.startsWith("ROLE_ADMIN_")){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 把企业信息 封装到userInfo中
     * @param userInfo
     * @param companyUserDTOList
     */
    public void wrapper(UserInfo userInfo, List<SysCompanyUserDTO> companyUserDTOList){
        if(companyUserDTOList != null && companyUserDTOList.size() == 1){
            SysCompanyUserDTO companyUserDTO = companyUserDTOList.get(0);

            userInfo.setCompanyId(companyUserDTO.getCompanyId()); //企业id
            userInfo.setCompanyName(companyUserDTO.getCompanyName()); //企业名称
            userInfo.setCompanyUserId(companyUserDTO.getId());//企业员工id
            userInfo.setDepartmentId(companyUserDTO.getDepartmentId()); //部门id
            userInfo.setDepartmentName(companyUserDTO.getDepartmentName()); //部门名称
            userInfo.setPost(companyUserDTO.getPost()); //职务
            userInfo.setWorkNumber(companyUserDTO.getWorkNumber()); //工号
            userInfo.setTimeEntry(companyUserDTO.getTimeEntry()); //入职时间
            userInfo.setEnable(true); //是否可用
        }
    }

    public AuthenticationProcessor chooseAuthenticationProcessor(IntegrationAuthenticationEntity entity){
        if (processorList!=null&&processorList.size()>0){
            for (AuthenticationProcessor processor : processorList) {
                boolean b = processor.support(entity);
                if (b){
                    return processor;
                }
            }
        }
        return null;
    }

}
